<?php
/**
 * Created by PhpStorm.
 * User: asus
 * Date: 2018/10/11
 * Time: 15:39
 */

namespace App\Libs\Common\Cache;

use App\Models\AdminMenu;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;

class PermissionMenu
{
    protected static $seconds = 3600; // 缓存时间 秒

    /**
     * Todo:: 缓存后台全部菜单信息
     * @param int $type
     * @return mixed
     */
    public static function allMenu($type = 0)
    {
        $cacheKey = 'admin_menu:all';
        if ($type == 1) {
            // 重新缓存
            if (Cache::has($cacheKey)) {     //判断是否存在
                Cache::forget($cacheKey);      //删除缓存
            }
        }
        if (Cache::has($cacheKey)) {     //判断是否存在
            $data = Cache::get($cacheKey);
        } else {
            $data = (new AdminMenu())->getAllMenu();
            Cache::add($cacheKey, $data, self::$seconds);
        }
        return $data;
    }

    /**
     * Todo:: 获取个人管理员菜单
     * @param $id
     * @return array|bool|mixed
     */
    public static function getAdminMenu($id)
    {
        $cacheKey = 'admin_menu:' . $id;
        if (Cache::has($cacheKey)) {     //判断是否存在
            $data = Cache::get($cacheKey);   // 获取用户独立缓存
        } else {
            $data = (new AdminMenu())->adminMenu(0);
            Cache::put($cacheKey, $data, self::$seconds);
        }
        return $data;
    }

    /**
     * Todo:: 判断菜单是否存在
     * @param $v
     * @param $address
     * @return bool|object
     */
    public static function ifMenuName($v, $address)
    {
        $allMenu = self::allMenu();
        foreach ($allMenu as $menu) {
            if ($menu['v'] == $v && $menu['address'] == $address) {
                return (Object)$menu;
            }
        }
        return false;
    }


    /**
     * Todo:: 单个管理员显示菜单 导航菜单
     * @param $id
     * @return array
     */
    public static function getAdminShowMenu($id)
    {
        $getAdminMenu = self::getAdminMenu($id);
        $showMenu = array();
        foreach ($getAdminMenu as $key => $val) {
            if(is_array($val)){
                if ($val['is_display'] == 1 && $val['is_type'] == 1) {
                    $showMenu[$key] = $val;
                }
            }elseif(is_object($val)){
                if ($val->is_display == 1 && $val->is_type == 1) {
                    $showMenu[$key] = objectToArray($val);
                }
            }
        }
        return $showMenu;
    }

    /**
     * Todo:: 单个管理员菜单HTML
     * @param $id
     * @return string
     */
    public static function myMenuHtml($id)
    {
        $menuTree = listToTree(self::getAdminShowMenu($id));

        $requestUrl = explode('?', $_SERVER['REQUEST_URI'])[0];
        $parentUrl = '';
        if ($requestUrl) {
            $mca = explode('/', $requestUrl);
            if(count($mca) > 2){
                if($mca[0]){
                    $pathM = $mca[0];
                    $pathV = $mca[1];
                    unset($mca[0],$mca[1]);
                }else{
                    $pathM = $mca[1];
                    $pathV = $mca[2];
                    unset($mca[0],$mca[1],$mca[2]);
                }
                $pathAddress = implode('/',$mca);
                $getMenu = self::menuInfo(0,$pathM,$pathV,$pathAddress);
                if($getMenu['parent_id'] && empty($getMenu['is_display'])){
                    $parentMenu = self::menuInfo($getMenu['parent_id']);
                    if($parentMenu['is_display'] == 1){
                        $parentUrl = '/' . $parentMenu['m'] . '/' . $parentMenu['v'] . '/' . $parentMenu['address'];
                    }
                }
            }
        }
        $html = '<ul class="nav nav-list">';
        $html .= self::menuTree($menuTree,$requestUrl,$parentUrl);
        $html .= "
                </ul>";
        return $html;
    }

    /**
     * 菜单组装成html
     * @param $tree
     * @return string
     */
    /**
     * Todo:: 菜单组装成html
     * @param $tree 菜单列表
     * @param string $requestUrl 请求地址
     * @param string $requestParentUrl 请求地址父级
     * @return string
     */
    private static function menuTree($tree,$requestUrl='',$requestParentUrl='')
    {
        $html = '';
        if (is_array($tree)) {
            foreach ($tree as $val) {
                if (isset($val["menu_name"])) {
                    $title = $val["menu_name"];
                    $url = '/' . $val['m'] . '/' . $val['v'] . '/' . $val['address'];
                    $val['data'] ? $url .= '?' . $val['data'] : '';
                    if (empty($val["id"])) {
                        $id = $val["menu_name"];
                    } else {
                        $id = $val["id"];
                    }
                    if (empty($val['icon'])) {
                        $icon = "fa-caret-right";
                    } else {
                        $icon = $val['icon'];
                    }

                    // 标示预览页面
                    $active = '';
                    if(empty($requestUrl)){
                        $requestUrl = explode('?', $_SERVER['REQUEST_URI'])[0];
                    }
                    if ($url == $requestUrl) {
                        $active = 'active';
                    }
                    if(!empty($requestParentUrl)){
                        if ($url == $requestParentUrl) {
                            $active = 'active';
                        }
                    }


                    if (isset($val['_child'])) {
                        $html .= '
                            <li class="">
                            <a href="' . $url . '" class="dropdown-toggle">
                                <i class="menu-icon fa ' . $icon . '"></i>
                                <span class="menu-text"> ' . $title . ' </span>
                                <b class="arrow fa fa-angle-down"></b>
                            </a>
                            <b class="arrow"></b>
                            <ul class="submenu">
                            ';
                        $html .= self::menuTree($val['_child'],$requestUrl,$requestParentUrl);
                        $html .= '
                            </ul>
                        </li>
                        ';
                    } else {
                        $html .= '
                    <li class = "' . $active . '">
                    <a href = "' . $url . '">
                    <i class = "menu-icon fa ' . $icon . '"></i>
                    <span class = "menu-text"> ' . $title . ' </span>
                    </a>
                    <b class = "arrow"></b>
                    </li>
                    ';
                    }
                }
            }
        }
        return $html;
    }


    /**
     * Todo:: 获取菜单信息
     * @param int $id
     * @param string $m
     * @param string $v
     * @param string $address
     * @return bool|mixed
     */
    public static function menuInfo($id=0, $m='', $v='', $address='')
    {
        $allMenu = self::allMenu();
        if ($allMenu) {
            foreach ($allMenu as $key => $val) {
                if($id){
                    if($val['id'] == $id){
                        return $val;
                    }
                }else{
                    if ($val['m'] == $m && $val['v'] == $v && $val['address'] == $address) {
                        return $val;
                    }
                }
            }
        }
        return false;
    }


    /**
     * Todo:: 获取菜单所有父级
     * @param $m
     * @param $v
     * @param $address
     * @param int $level
     * @param array $parentData
     * @return array
     */
    public static function menuParent($m, $v, $address, $level = 1, $parentData = [])
    {
        $menuInfo = self::menuInfo(0,$m, $v, $address);
        if ($menuInfo) {
            if ($menuInfo['parent_id']) {
                $parentMenu = self::menuInfo($menuInfo['parent_id']);
                if($parentMenu){
                    $parentMenu['level'] = $level;
                    $parentMenu['path_url'] = "/{$parentMenu['m']}/{$parentMenu['v']}/{$parentMenu['address']}";
                    if($parentMenu['parent_id']  == 0){
                        $parentMenu['path_url'] = "#";
                    }
                    array_push($parentData,$parentMenu);
                    $level++;
                    return self::menuParent($parentMenu['m'], $parentMenu['v'], $parentMenu['address'], $level, $parentData);
                }
            }
        }
        return $parentData;
    }

    /**
     * Todo:: 无限获取下级
     * @param $parenId
     * @return array
     */
    public static function menuChild($parenId){
        $allMenu = self::allMenu();
        $childData = self::getMember($allMenu,$parenId);
        $ids = [];
        if($childData){
            foreach($childData as $key=>$val){
                $ids[] = $val['id'];
            }
        }
        return array('data'=>$childData,'ids'=>$ids);
    }


    /**
     * Todo:: 无限获取 下级
     * @param $data
     * @param $pid
     * @param int $level
     * @return array
     */
    private static function getMember($data , $pid ,$level = 0)
    {
        $arr = array();
        foreach($data as $key => $val){
            if($val['parent_id'] == $pid){
                $val['level'] = $level+1;
                $arr[]=$val;
                $arr = array_merge($arr,self::getMember($data,$val['id'],$level+1));
            }
        }
        return $arr;
    }




    /**
     * Todo:: 清除个人管理员 缓存 菜单信息
     * @param $id
     */
    public static function getCleanUpMyMenu($id)
    {
        $sessionName = array('admin_menu:' . $id);
        foreach ($sessionName as $key => $val) {
            if (Cache::has($val)) {
                Cache::forget($val);      //删除缓存
            }
        }
    }

    /**
     * Todo:: 清除全部管理员 缓存 菜单信息
     */
    public static function getCleanUpAllMenu()
    {
        $allAdmin = DB::table('admin_user')->select(array('id'))->get();
        foreach ($allAdmin as $key => $val) {
            self::getCleanUpMyMenu($val->id);
        }
    }

    /**
     * Todo:: 判断是否拥有菜单权限
     * @param string $v
     * @param $address
     * @return bool
     */
    public static function getPermission($v, $address)
    {
        $adminUser = request()->user('admin');
        //公开菜单
//        if (preg_match('/^public/', $a)) {
//            return true;
//        }
        if (in_array($address, self::publicMenu())) {
            return true;
        }
        //超级管理员请求
        if ($adminUser->is_super == 1 || $adminUser->id == 1) {
            return true;
        }
        $myMenu = self::getAdminMenu($adminUser->id);
        $isMenu = self::ifMenuName($v, $address);
        //没有分配菜单
        if (!$myMenu || !isset($isMenu->id)) {
            return false;
        }
        //访问菜单不在自己菜单中
        if (!in_array($isMenu->id, array_column($myMenu, 'id'))) {
            return false;
        }
        return true;
    }

    /**
     * Todo:: 公共菜单地址列表
     * @return array
     */
    public static function publicMenu()
    {
        return array(
            'home/index',
            'common/msg',
        );
    }

}
